#include <pthread.h>
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define QUEUE_SIZE 10
typedef struct
{
    int data[QUEUE_SIZE];
    int front;
    int rear;
} CircularQueue;

CircularQueue queue;
sem_t mutex;
sem_t empty;
sem_t full;

void init()
{
    queue.front = queue.rear = 0;
    sem_init(&mutex,0,1);
    sem_init(&empty,0,QUEUE_SIZE);
    sem_init(&full,0,0);
}

void* producer(void*arg)
{
    int item;
    while(1)
    {
        item = rand()%100;
        sem_wait(&empty);
        sem_wait(&mutex);

        queue.data[queue.rear] = item;
        queue.rear = (queue.rear+1)%QUEUE_SIZE;
        printf("Producer produced %d\n",item);
        sem_post(&mutex);
        sem_post(&full);
        sleep(1);
    }
}
void*consumer(void*arg)
{
    int item;
    while(1)
    {
        sem_wait(&full);
        sem_wait(&mutex);
        item = queue.data[queue.front];
        queue.front = (queue.front+1)% QUEUE_SIZE;

        printf("Consumer consumed %d\n",item);
        sem_post(&mutex);
        sem_post(&empty);
        sleep(1);
    }
}

int main()
{
    pthread_t prod_thread,cons_thread;
    init();

    pthread_create(&prod_thread,NULL,producer,NULL);
    pthread_create(&cons_thread,NULL,consumer,NULL);

    pthread_join(prod_thread,NULL);
    pthread_join(cons_thread,NULL);

    return 0;
}